<?php

/**
 * Модель поиска
 */
class SearchModel extends DbModel {

    protected $_name = 'page_editor';

    /**
     * Поиск по содержимому страниц (пока WYSYWIG)
     *
     * @param string $query Запрос
     * @param int $page Страница
     * @return mixed
     */
    public function search($query, $page = 1) {
        //Editor
        $select = 'SELECT ' .PREFIX . 'page_editor.sid,' .PREFIX . 'page_editor.content,' .PREFIX . 'pages.id,' .PREFIX . 'pages.url,' .PREFIX . "pages.name as title, 'editor' as module FROM " .PREFIX . 'page_editor, ' .PREFIX . 'sections, ' .PREFIX . 'pages WHERE (' .PREFIX . 'page_editor.sid = ' .PREFIX . 'sections.id AND ' .PREFIX . 'sections.pid = ' .PREFIX . 'pages.id AND ' .PREFIX . 'sections.bid = 0) AND MATCH (' .PREFIX . "page_editor.content) AGAINST ('" . $query . "')";
        $res = $this->_db->fetchAll($select);

        //News
        $select = 'SELECT ' .PREFIX . 'page_news.title,' .PREFIX . 'page_news.sid,' .PREFIX . 'page_news.long as content,' .PREFIX . 'page_news.id as post,' .PREFIX . 'page_news.date,pages.id,' .PREFIX . "pages.url, 'news' as module FROM " .PREFIX . 'page_news, ' .PREFIX . 'sections, ' .PREFIX . 'pages WHERE (' .PREFIX . 'page_news.sid = ' .PREFIX . 'sections.id AND ' .PREFIX . 'sections.pid = ' .PREFIX . 'pages.id AND ' .PREFIX . 'sections.bid = 0) AND MATCH (' .PREFIX . "page_news.long) AGAINST ('" . $query . "')";
        $res2 = $this->_db->fetchAll($select);

        $results = array_merge($res, $res2);

        $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($results));
        $paginator->setCurrentPageNumber($page);
        $model = new PaginatorModel();
        return $model->get($paginator);
    }

    /**
     * Удаление секции с поиском - ничего не происходит
     */
    public function deleteSection() {
        
    }

    /**
     * Показывает результат поиска с вырезанием нужного блока
     *
     * @param string $text Текст
     * @param string $phrase Поисковый запрос
     * @param int $span Кол-во символов для показа
     * @param string $delimiter Разделитель отрывка текста
     * @return string Отформатированный текст
     */
    public function excerpt($text, $phrase, $span = 100, $delimiter = '...') {
        $phrases = preg_split('/\s+/', $phrase);
        $regexp = '/\b(?:';
        foreach ($phrases as $phrase) {
            $regexp .= preg_quote($phrase, '/') . '|';
        }
        $regexp = substr($regexp, 0, -1) . ')\b/i';
        $matches = array();
        preg_match_all($regexp, $text, $matches, PREG_OFFSET_CAPTURE);
        $matches = $matches[0];
        $nodes = array();
        foreach ($matches as $match) {
            $node = new stdClass;
            $node->phraseLength = strlen($match[0]);
            $node->position = $match[1];
            $nodes[] = $node;
        }
        if (count($nodes) > 0) {
            $clust = new stdClass;
            $clust->nodes[] = array_shift($nodes);
            $clust->length = $clust->nodes[0]->phraseLength;
            $clust->i = 0;
            $clusters = new stdClass;
            $clusters->data = array($clust);
            $clusters->i = 0;
            foreach ($nodes as $node) {
                $lastClust = $clusters->data[$clusters->i];
                $lastNode = $lastClust->nodes[$lastClust->i];
                $addedLength = $node->position - $lastNode->position - $lastNode->phraseLength + $node->phraseLength;
                if ($lastClust->length + $addedLength <= $span) {
                    $lastClust->nodes[] = $node;
                    $lastClust->length += $addedLength;
                    $lastClust->i += 1;
                } else {
                    if ($addedLength > $span) {
                        $newClust = new stdClass;
                        $newClust->nodes = array($node);
                        $newClust->i = 0;
                        $newClust->length = $node->phraseLength;
                        $clusters->data[] = $newClust;
                        $clusters->i += 1;
                    } else {
                        $newClust = clone $lastClust;
                        while ($newClust->length + $addedLength > $span) {
                            $shiftedNode = array_shift($newClust->nodes);
                            if ($shiftedNode === null) {
                                break;
                            }
                            $newClust->i -= 1;
                            $removedLength = $shiftedNode->phraseLength;
                            if (isset($newClust->nodes[0])) {
                                $removedLength += $newClust->nodes[0]->position - $shiftedNode->position;
                            }
                            $newClust->length -= $removedLength;
                        }
                        if ($newClust->i < 0) {
                            $newClust->i = 0;
                        }
                        $newClust->nodes[] = $node;
                        $newClust->length += $addedLength;
                        $clusters->data[] = $newClust;
                        $clusters->i += 1;
                    }
                }
            }
            $bestClust = $clusters->data[0];
            $bestClustSize = count($bestClust->nodes);
            foreach ($clusters->data as $clust) {
                $newClustSize = count($clust->nodes);
                if ($newClustSize > $bestClustSize) {
                    $bestClust = $clust;
                    $bestClustSize = $newClustSize;
                }
            }
            $clustLeft = $bestClust->nodes[0]->position;
            $clustLen = $bestClust->length;
            $padding = round(($span - $clustLen) / 2);
            $clustLeft -= $padding;
            if ($clustLeft < 0) {
                $clustLen += $clustLeft * -1 + $padding;
                $clustLeft = 0;
            } else {
                $clustLen += $padding * 2;
            }
        } else {
            $clustLeft = 0;
            $clustLen = $span;
        }
        $textLen = strlen($text);
        $prefix = '';
        $suffix = '';
        if (!ctype_space($text[$clustLeft]) && isset($text[$clustLeft - 1]) && !ctype_space($text[$clustLeft - 1])) {
            while (!ctype_space($text[$clustLeft])) {
                $clustLeft += 1;
            }
            $prefix = $delimiter;
        }
        $lastChar = $clustLeft + $clustLen;

        if (isset($text[$lastChar]) && !ctype_space($text[$lastChar]) && isset($text[$lastChar + 1]) && !ctype_space($text[$lastChar + 1])) {
            while (!ctype_space($text[$lastChar])) {
                $lastChar -= 1;
            }
            $suffix = $delimiter;
            $clustLen = $lastChar - $clustLeft;
        }

        if ($clustLeft > 0) {
            $prefix = $delimiter;
        }
        if ($clustLeft + $clustLen < $textLen) {
            $suffix = $delimiter;
        }
        return $prefix . trim(substr($text, $clustLeft, $clustLen + 1)) . $suffix;
    }

}

